﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace Tin
{
    public partial class Form1 : Form
    {
        private List<TPoint> _points;
        private List<TTriangle> _tris;
        private double _height;
        private Matrix _transform;
        private PointF _mouse_pos;

        public Form1()
        {
            InitializeComponent();
            this.drawPanel.MouseWheel += new MouseEventHandler(drawPanel_MouseWheel);
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {

        }

        private void updateGridView()
        {
            dataGridView1.DataSource = Report.GetTable(_points);

        }

        private void 打开OToolStripButton_Click(object sender, EventArgs e)
        {
            var openDiag = new OpenFileDialog();
            openDiag.Filter = "txt file ( *.txt ) | *.txt";

            if (openDiag.ShowDialog() == DialogResult.OK && openDiag.CheckPathExists)
            {
                FileManager.FileOpen(openDiag.FileName, out _points, out _height);
                updateGridView();
                initScale();
            }
        }

        private void 计算ToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            if (_points != null)
            {
                Tin tin = new Tin(_points);
                _tris = tin.GetTin();
                drawPanel.Refresh();
            }

        }

        private void drawPanel_Click(object sender, EventArgs e)
        {

        }

        private void initScale()
        {
            float w = drawPanel.Width;
            float h = drawPanel.Height;
            float max_left = Convert.ToSingle(_points.Min(t => t.X));
            float max_right = Convert.ToSingle(_points.Max(t => t.X));
            float max_top = Convert.ToSingle(_points.Max(t => t.Y));
            float max_bottom = Convert.ToSingle(_points.Min(t => t.Y));

            float data_width = max_right - max_left;
            float data_height = max_top - max_bottom;
            float sx = w / (data_width * 1.02f);
            float sy = h / (data_height * 1.02f);
            float dx = 0.0f;
            float dy = 0.0f;
            if (sx > sy)
            {
                sx = sy;
                dx = (data_width - w / sx) / 2.0f; // 调整横向比例，横向居中
            }
            else
            {
                sy = sx;
                dy = (data_height - h / sy) / 2.0f; // 调整纵向比例，纵向居中
            }
            Matrix new_trans = new Matrix();

            new_trans.Scale(sx, -sy);
            new_trans.Translate(-max_left + data_width * 0.01f - dx,
                -max_top - data_height * 0.01f + dy);
            _transform = new_trans;
        }



        private void drawPanel_Paint(object sender, PaintEventArgs e)
        {
            if (_points == null) return;

            Graphics g = e.Graphics;
            g.Clear(Color.White);
            g.Transform = _transform;

            if (_tris != null)
                for (int i = 0; i < _tris.Count; i++)
                    _tris[i].render(g);

            for (int i = 0; i < _points.Count; i++)
                _points[i].render(g);
        }

        private void drawPanel_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            initScale();
            drawPanel.Refresh();
        }

        private void drawPanel_MouseMove(object sender, MouseEventArgs e)
        {
            if (_points.Count != 0)
            {
                PointF now_pos = new PointF(e.X, e.Y);
                PointF[] pos_coord = new PointF[1];
                pos_coord[0] = now_pos;
                if (e.Button == MouseButtons.Left)
                {
                    this.Cursor = Cursors.Hand;
                    PointF[] pos = new PointF[2];
                    pos[0] = _mouse_pos;
                    pos[1] = now_pos;
                    var trans_inv = _transform.Clone();
                    trans_inv.Invert();
                    trans_inv.TransformPoints(pos);
                    float dx = pos[1].X - pos[0].X;
                    float dy = pos[1].Y - pos[0].Y;
                    _transform.Translate(dx, dy);
                    drawPanel.Refresh();
                }

            }
            _mouse_pos = new PointF(e.X, e.Y);
        }

        private void drawPanel_MouseWheel(object sender, MouseEventArgs e)
        {
            if (_points.Count > 0)
            {
                PointF now_pos = new PointF(e.X, e.Y);
                PointF[] pos = new PointF[1];
                pos[0] = now_pos;
                var trans_inv = _transform.Clone();
                trans_inv.Invert();
                trans_inv.TransformPoints(pos);
                if (e.Delta > 0)
                    _transform.Scale(e.Delta / 100f, e.Delta / 100f);
                else
                    _transform.Scale(-100f / e.Delta, -100f / e.Delta);
                PointF[] pos_scale = new PointF[1];
                pos_scale[0] = now_pos;
                trans_inv = _transform.Clone();
                trans_inv.Invert();
                trans_inv.TransformPoints(pos_scale);
                float dx = pos_scale[0].X - pos[0].X;
                float dy = pos_scale[0].Y - pos[0].Y;
                _transform.Translate(dx, dy);
                drawPanel.Refresh();
            }
        }

        private void drawPanel_MouseDown(object sender, MouseEventArgs e)
        {
            //this.Cursor = Cursors.Default;
        }

        private void drawPanel_MouseUp(object sender, MouseEventArgs e)
        {
            this.Cursor = Cursors.Default;

        }

        private void 打开ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            打开OToolStripButton_Click(sender, e);
        }
    }
}
